package com.allwees.core.elasticsearch.configuration;

import com.allwees.core.elasticsearch.http.Method;
import com.allwees.core.elasticsearch.query.ScriptRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.UpdateByQueryRequest;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;


@Slf4j
public class ElasticsearchScriptTemplate {
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    public ElasticsearchScriptTemplate(ElasticsearchRestTemplate elasticsearchRestTemplate) {
        this.elasticsearchRestTemplate = elasticsearchRestTemplate;
    }

    public String performRequest(ScriptRequest request) {
        return performRequest(request.getMethod(), request.getUrl(), request.getParams().parse(request.getScript()));
    }

    public String performRequest(Method method, String url, String script) {
        Request request = new Request(method.name(), url);
        request.setJsonEntity(_parseTxtJson(script));
        Response response = null;
        try {
            response = elasticsearchRestTemplate.getClient().getLowLevelClient().performRequest(request);
    		return IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
        } catch (IOException e) {
            log.error("perform request error: {url:{}, method:{}, script:{}}", url, method, script, e);
            return "{}";
        }
    }

    public long  updateSingleFieldByCondition(String indexName,String conditionFieldName, String conditionValue,String targetFieldName,String targetValue){
        RestHighLevelClient client = elasticsearchRestTemplate.getClient();
        //参数为索引名，可以不指定，可以一个，可以多个
        UpdateByQueryRequest request = new UpdateByQueryRequest(indexName);
        // 更新时版本冲突
        request.setConflicts("proceed");
        // 设置查询条件，第一个参数是字段名，第二个参数是字段的值
        request.setQuery(new TermQueryBuilder(conditionFieldName, conditionValue));
        // 更新最大文档数
        request.setSize(10);
        // 批次大小
        request.setBatchSize(1000);
//		request.setPipeline("my_pipeline");

        request.setScript(new Script(ScriptType.INLINE, "painless",
                "if (ctx._source."+conditionFieldName+" == '"+conditionValue+"') {ctx._source."+targetFieldName+" = '"+targetValue+"';}", Collections.emptyMap()));
        // 并行
        request.setSlices(2);
        // 使用滚动参数来控制“搜索上下文”存活的时间
        request.setScroll(TimeValue.timeValueMinutes(10));
        // 如果提供路由，则将路由复制到滚动查询，将流程限制为匹配该路由值的切分
//		request.setRouting("=cat");

        // 可选参数
        // 超时
        request.setTimeout(TimeValue.timeValueMinutes(2));
        // 刷新索引
        request.setRefresh(true);

        try {
            BulkByScrollResponse response = client.updateByQuery(request, RequestOptions.DEFAULT);

            return response.getStatus().getUpdated();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return -1;
    }

    private String _parseTxtJson(String script) {
    	return script.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\t", " ");
    }
}
